using System;
using System.Collections.Generic;
using System.Text;

namespace MobileTDL
{
	public class ItemEventArgs<T> : EventArgs
	{
		private int _Index = -1;
		private T _Item = default(T);

		public ItemEventArgs(int index, T item)
		{
			Index = index;
			Item = item;
		}

		public int Index
		{
			get { return _Index; }
			set { _Index = value; }
		}

		public T Item
		{
			get { return _Item; }
			set { _Item = value; }
		}
	}

	public class ItemSetEventArgs<T> : EventArgs
	{
		private int _index = -1;
		private T _newItem = default(T);
		private T _oldItem = default(T);

		public ItemSetEventArgs(int index, T oldItem, T newItem)
		{
			Index = index;
			NewItem = newItem;
			OldItem = oldItem;
		}

		public int Index
		{
			get { return _index; }
			set { _index = value; }
		}

		public T NewItem
		{
			get { return _newItem; }
			set { _newItem = value; }
		}

		public T OldItem
		{
			get { return _oldItem; }
			set { _oldItem = value; }
		}
	}

	public interface INotifyingList<T> : IList<T>
	{
		event EventHandler<ItemEventArgs<T>> ItemAdded;
		event EventHandler<ItemEventArgs<T>> ItemRemoved;
		event EventHandler<ItemSetEventArgs<T>> ItemSet;
	}

	public class NotifyingList<T> : List<T>, INotifyingList<T>
	{
		public event EventHandler<ItemEventArgs<T>> ItemAdded;
		public event EventHandler<ItemEventArgs<T>> ItemRemoved;
		public event EventHandler<ItemSetEventArgs<T>> ItemSet;

		new public T this[int index]
		{
			get { return base[index]; }
			set
			{
				if (!value.Equals(base[index]))
				{
					T oldItem = default(T);
					oldItem = base[index];
					base[index] = value;
					OnItemSet(new ItemSetEventArgs<T>(index, oldItem, value));
				}
			}
		}

		new public void Add(T item)
		{
			base.Add(item);
			int index = base.IndexOf(item);
			OnItemAdded(new ItemEventArgs<T>(index, item));
		}

		virtual protected void OnItemAdded(ItemEventArgs<T> args)
		{
			if (ItemAdded != null) ItemAdded(this, args);
		}

		virtual protected void OnItemSet(ItemSetEventArgs<T> args)
		{
			if (ItemSet != null) ItemSet(this, args);
		}

		virtual protected void OnItemRemoved(ItemEventArgs<T> args)
		{
			if (ItemRemoved != null) ItemRemoved(this, args);
		}

		new public void Remove(T item)
		{
			int index = base.IndexOf(item);
			base.Remove(item);
			OnItemRemoved(new ItemEventArgs<T>(index, item));
		}

		//public void RemoveAll()
		//{
		//  for (int i = Count - 1; i >= 0; i--) RemoveAt(i);
		//}

		new public void RemoveAt(int index)
		{
			if (Count > index) Remove(this[index]);
		}
	}
}
